﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Soft
{
    [Serializable]
    public class Result : baseObject, IResult, IError
    {
    
        public Result()
        {
            this.Error = new InformationCollection();
            this.Error.InformationListChanged += delegate (List<Information> e)
            {
                this.mSucceed = (e.Count == 0);
            };
        }

        public Result(string error, object sender = null) : this()
        {
            this.AddError(error, sender);
        }


        public Result(IResult result) : this()
        {
            this.ReceiveResult(result);
        }

 
        public Result(Exception e, object sender = null) : this()
        {
            this.AddError(e, sender);
        }

        public void ClearError()
        {
            this.Error.Clear();
            this.ErrorCode = 0;
        }

        public void AddError(string text, object sender = null)
        {
            this.Error.Add(new Information(InformationType.Error, text, sender));
            if (this.ErrorCode == 0)
            {
                this.ErrorCode = -1;
            }
        }

  
        public void AddError(IResult result)
        {
            if (result == null)
            {
                throw new ArgumentNullException("result");
            }
            if (!result.Succeed)
            {
                this.Error.AddRange(result.Error);
                if (this.ErrorCode == 0)
                {
                    this.ErrorCode = -1;
                }
            }
        }

      
        public void AddError(Exception exception, object sender = null)
        {
            if (exception == null)
            {
                throw new ArgumentNullException("exception");
            }
            this.Error.Add(new Information(exception, sender));
            if (this.ErrorCode == 0)
            {
                this.ErrorCode = -1;
            }
        }

     
        public void AddError(IErrorMessage e)
        {
            if (e == null)
            {
                throw new ArgumentNullException("e");
            }
            this.ErrorCode = e.Code;
            this.AddError(e.Message, null);
        }

        /// <summary>
        /// 检查任务结果
        /// </summary>
        /// <param name="result"></param>
        public void ReceiveResult(IResult result)
        {
            if (result == null)
            {
                throw new ArgumentNullException("result");
            }
            if (!result.Succeed)
            {
                this.AddError(result);
                this.ErrorCode = result.ErrorCode;
            }
            this.NotAuthorized = result.NotAuthorized;
        }

        public virtual void SetNotAuthorized(string functionCode)
        {
            this.RequestFunctionCode = functionCode;
            this.NotAuthorized = true;
        }

    
        public virtual void SetNotAuthorized(IResult result)
        {
            if (result == null)
            {
                throw new ArgumentNullException("result");
            }
            this.RequestFunctionCode = result.RequestFunctionCode;
            this.NotAuthorized = true;
        }


        public bool Succeed
        {
            get
            {
                return this.mSucceed;
            }
            set
            {
                this.mSucceed = value;
            }
        }

     
        public bool NotAuthorized
        {
            get
            {
                return this.mNotAuthorized;
            }
            set
            {
                if (value)
                {
                    this.mNotAuthorized = value;
                    if (string.IsNullOrEmpty(this.RequestFunctionCode))
                    {
                        this.AddError("Function code is not authorized.", null);
                        return;
                    }
                    this.AddError("This function code '" + this.RequestFunctionCode + "' is not authorized.", null);
                }
            }
        }

        public string RequestFunctionCode { get; set; } = string.Empty;


        public InformationCollection Error { get; set; }


        public int ErrorCode { get; set; }


        public string ToJson()
        {
            return JsonConvert.SerializeObject(this);
        }

        private bool mSucceed = true;


        private bool mNotAuthorized;


        public static readonly Result Done = new Result();
    }
}
